﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using COFE.Core.Utils;
using COFE.Core;

namespace COFE.Core.Lister
{
    public abstract class VirtualFileStream<T> : FileStream
    {
        public VirtualFileStream(IInternalFileInfoExA file, FileMode mode, FileAccess access)
            : base(getFilePath(file), mode, access)
        {
            _file = file;
            _access = access;
            _mode = mode;
            _isModified = false;
        }

        

        #region Methods

        protected T getEmbeddedItem(IInternalFileSystemInfoExA entry)
        {
            return (T)entry.GetProperty(InternalProperties.EmbeddedEntry).Value;
        }

        private static string getFilePath(IFileInfo file)
        {
            IInternalFileInfoExA iFile = file as IInternalFileInfoExA;
            if (iFile.Exists)
                return iFile.FullName;
            else return iFile.TempPath;
        }

         public override void Write(byte[] buffer, int offset, int count)
        {
            base.Write(buffer, offset, count);
            _isModified = true;
        }

        public override void WriteByte(byte value)
        {
            base.WriteByte(value);
            _isModified = true;
        }

        public override void EndWrite(IAsyncResult asyncResult)
        {
            base.EndWrite(asyncResult);
            _isModified = true;
        }
        

        public virtual void CallUpdateProc()
        {
            if (_isModified)
            {
                bool exists = _file.Exists; //Whether the file already exists?

                _updateProc(getEmbeddedItem(_file), _file.TempPath);

                _file.AlertModified(exists ? ModifiedAction.Changed : ModifiedAction.Created);
                _file.Refresh();

                _isModified = false;
            }
        }

        protected override void Dispose(bool disposing)
        {
            
            base.Dispose(disposing);
        }

        public override void Close()
        {
            base.Close();
            CallUpdateProc();
        }

        //public override void Close()
        //{
        //    base.Close();
        //    if (_access != FileAccess.Read)
        //    {
        //        (_file as IInternalFileInfoExA).UpdateSource();
        //        _file.AlertModified(ModifiedAction.Changed);
        //        _file.Refresh();
        //    }
        //}

        #endregion

        #region Data

        protected Action<T, string> _updateProc = (item, tempPath) => { throw new NotImplementedException(); };
        private FileAccess _access;
        private FileMode _mode;
        private IInternalFileInfoExA _file;
        private bool _isModified;

        #endregion
    }
}
